home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 May: Tool Chest / Dev.CD May 97 TC.toast / Sample Code / Toolbox / MacCalendar 1.1b1 / MacCalendarSetup.c < prev    next >
Encoding:
Text File  |  1997-03-20  |  14.7 KB  |  648 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        MacCalendarSetup.c
  3.  
  4.     Contains:    Application for configuring the control strip.
  5.  
  6.     Written by:    Martin Minow
  7.  
  8.     Copyright:    © 1994-1997 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.     You may incorporate this sample code into your applications without
  13.     restriction, though the sample code has been provided "AS IS" and the
  14.     responsibility for its operation is 100% yours.  However, what you are
  15.     not permitted to do is to redistribute the source as "DSC Sample Code"
  16.     after having made changes. If you're going to re-distribute the source,
  17.     we require that you make it clear in the source that the code was
  18.     descended from Apple Sample Code, but that you've made changes.
  19.  
  20.     Sets the configuration parameters for MacCalendar
  21.  
  22.     File Type            APPL
  23.     File Creator        SCCF    -- registered with DTS
  24.  */
  25.  
  26. /////////////////////////////////////////////////////////////////////////
  27.  
  28. // Pick up resource constants common to both control strip
  29. // module and application.
  30.  
  31. #include "MacCalendarCommon.h"
  32.  
  33. /////////////////////////////////////////////////////////////////////////
  34.  
  35. // Pick up resource constants common to both C and Rez for
  36. // the application.
  37.  
  38. #include "MacCalendarSetup.h"
  39.  
  40. /////////////////////////////////////////////////////////////////////////
  41.  
  42. // Pick up prototype for the core drawing code.
  43.  
  44. #include "DrawCalendar.h"
  45.  
  46. /////////////////////////////////////////////////////////////////////////
  47.  
  48. #include <Dialogs.h>
  49. #include <Errors.h>
  50. #include <Fonts.h>
  51. #include <Memory.h>
  52. #include <Menus.h>
  53. #include <Quickdraw.h>
  54. #include <Resources.h>
  55. #include <ToolUtils.h>
  56. #include <Types.h>
  57. #include <Gestalt.h>
  58. #include <Processes.h>
  59.  
  60. /////////////////////////////////////////////////////////////////////////
  61.  
  62. // Various globals and constants.
  63.  
  64. // Indices into the STRN_Messages STR# resource.
  65.  
  66. enum {
  67.     kMsgSystemError = 1
  68. };
  69.  
  70. /*
  71.  * Items in the setup dialog ('DITL' ID=DLOG_Setup).
  72.  *
  73.  * Note: kOKButton is also used for Alerts.
  74.  */
  75. enum {
  76.     kOKButton = 1,
  77.     kCancelButton,
  78.     kCalendarUserItem,
  79.     kFontNamePopupItem,
  80.     kFontSizePopupItem,
  81.     kFirstDayPopupItem,
  82.     kDayNameUserItem,
  83.     kSundayText,            /* Day names must be in order    */
  84.     kMondayText,
  85.     kTuesdayText,
  86.     kWednesdayText,
  87.     kThursdayText,
  88.     kFridayText,
  89.     kSaturdayText,
  90. #if DEBUG
  91.     kPrevMonth,
  92.     kNextMonth,
  93. #endif
  94.     kDummyLastEnumBecauseWeCare    
  95. };
  96.  
  97. DialogPtr            gSetupDialog;
  98. short                gAppResourceFile;
  99.  
  100. SavedSettingsHandle    gSettingHandle = NULL;
  101.  
  102. DateTimeRec            gNow;
  103.  
  104. /////////////////////////////////////////////////////////////////////////
  105.  
  106. // Boiler plate error dialogs.
  107.  
  108. static void
  109. ErrorAlert(
  110.         short                    alertID,
  111.         OSErr                    errorStatus,
  112.         short                    errorMsgID
  113.     )
  114. {
  115.         Handle                    errorTextHdl;
  116.         Str15                    errorStatusText;
  117.         short                    userChoice;
  118.         Str255                    errorMsgText;
  119.         Str255                    errorText;
  120.         short                    saveResFile;
  121.         
  122.         saveResFile = CurResFile();
  123.         UseResFile(gAppResourceFile);
  124.         GetIndString(errorMsgText, STRN_Messages, errorMsgID);
  125.         NumToString(errorStatus, errorStatusText);
  126.         errorTextHdl = GetResource('Estr', errorStatus);
  127.         if (errorTextHdl != NULL)
  128.             pstrcpy(errorText, *errorTextHdl);
  129.         else {
  130.             GetIndString(errorText, STRN_Messages, kMsgSystemError);
  131.         }
  132.         ParamText(errorStatusText, errorText, errorMsgText, "\p");
  133.         userChoice = StopAlert(alertID, NULL);
  134.         UseResFile(saveResFile);
  135.         if (alertID == ALRT_FatalError || userChoice == kOKButton)
  136.             ExitToShell();
  137. }
  138.  
  139. static void
  140. NonFatalError(
  141.         OSErr                    errorStatus,
  142.         short                    errorMsgID
  143.     )
  144. {
  145.         ErrorAlert(ALRT_NonFatalError, errorStatus, errorMsgID);
  146. }
  147.  
  148. static void
  149. FatalError(
  150.         OSErr                    errorStatus,
  151.         short                    errorMsgID
  152.     )
  153. {
  154.         ErrorAlert(ALRT_FatalError, errorStatus, errorMsgID);
  155. }
  156.  
  157. /////////////////////////////////////////////////////////////////////////
  158.  
  159. static UserItemUPP gDrawDayNameUserItemUPP;
  160.  
  161. static pascal void
  162. DrawDayNameUserItem(
  163.         DialogPtr                theDialog,
  164.         short                    itemNumber
  165.     )
  166. {
  167.         short                    itemType;
  168.         Handle                    itemHandle;
  169.         Rect                    itemRect;
  170.         Rect                    dayNameRect;
  171.         short                    i;
  172.         Str255                    work;
  173.         Intl1Rec                **itlHandle;
  174.         GrafPtr                    savePort;
  175.         short                    saveFontNumber;
  176.         short                    saveFontSize;
  177.         
  178.         GetPort(&savePort);
  179.         SetPort(theDialog);
  180.         saveFontNumber = theDialog->txFont;
  181.         saveFontSize = theDialog->txSize;
  182.         GetDialogItem(
  183.             theDialog,
  184.             itemNumber,
  185.             &itemType,
  186.             &itemHandle,
  187.             &dayNameRect
  188.         );
  189.         itlHandle = (Intl1Rec **) GetIntlResource(1);
  190.         for (i = 0; i < 7; i++) {
  191.             /*
  192.              * Get the string, abbreviate it, and draw it in the
  193.              * day name rectangle, tabbed over the associated
  194.              * edit text area. Messy, but it looks nicer.
  195.              */
  196.             pstrcpy(work, (**itlHandle).days[i]);
  197.             GetDialogItem(
  198.                 theDialog,
  199.                 kSundayText + i,
  200.                 &itemType,
  201.                 &itemHandle,
  202.                 &itemRect
  203.             );
  204.             itemRect.top = dayNameRect.top;
  205.             itemRect.bottom = dayNameRect.bottom;
  206.             TETextBox(
  207.                 &work[1],
  208.                 (**itlHandle).abbrLen,
  209.                 &itemRect,
  210.                 teJustLeft
  211.             );
  212.         }
  213.         TextFont(saveFontNumber);
  214.         TextSize(saveFontSize);
  215.         SetPort(savePort);
  216. }
  217.  
  218. /////////////////////////////////////////////////////////////////////////
  219.  
  220. static void
  221. AddThisDayName(
  222.         short                    dayNumber
  223.     )
  224. {
  225.         short                    itemType;
  226.         Handle                    itemHandle;
  227.         Rect                    itemRect;
  228.         Str255                    work;
  229.  
  230.         GetDialogItem(
  231.             gSetupDialog,
  232.             dayNumber,
  233.             &itemType,
  234.             &itemHandle,
  235.             &itemRect
  236.         );
  237.         GetDialogItemText(itemHandle, work);
  238.         BlockMoveData(
  239.             work,
  240.             &(**gSettingHandle).dayNameString[(**gSettingHandle).dayNameString[0] + 1],
  241.             work[0] + 1
  242.         );
  243.         (**gSettingHandle).dayNameString[0] += (work[0] + 1);
  244. }
  245.  
  246. /////////////////////////////////////////////////////////////////////////
  247.  
  248. static void
  249. RebuildDayNameText(void)
  250. {
  251.         short                        i;
  252.         
  253.         (**gSettingHandle).dayNameString[0] = 0;
  254.         if ((**gSettingHandle).firstDayOfWeek == kFirstIsMonday) {
  255.             for (i = kMondayText; i <= kSaturdayText; i++)
  256.                 AddThisDayName(i);
  257.             AddThisDayName(kSundayText);
  258.         }
  259.         else {
  260.             for (i = kSundayText; i <= kSaturdayText; i++)
  261.                 AddThisDayName(i);
  262.         }
  263.         (**gSettingHandle).dayNameString[++(**gSettingHandle).dayNameString[0]] = 0;
  264. }
  265.  
  266. /////////////////////////////////////////////////////////////////////////
  267.  
  268. static UserItemUPP gDrawCalendarUserItemUPP;
  269.  
  270. static pascal void
  271. DrawCalendarUserItem(
  272.         DialogPtr                theDialog,
  273.         short                    itemNumber
  274.     )
  275. {
  276.         short                    itemType;
  277.         Handle                    itemHandle;
  278.         Rect                    itemRect;
  279.         short                    fontNumber;
  280.         GrafPtr                    savePort;
  281.         short                    saveFontNumber;
  282.         short                    saveFontSize;
  283.         RgnHandle                saveRgn;
  284.         
  285.         RebuildDayNameText();
  286.         GetPort(&savePort);
  287.         SetPort(theDialog);
  288.         saveFontNumber = theDialog->txFont;
  289.         saveFontSize = theDialog->txSize;
  290.         GetDialogItem(
  291.             theDialog,
  292.             itemNumber,
  293.             &itemType,
  294.             &itemHandle,
  295.             &itemRect
  296.         );
  297.         EraseRect(&itemRect);
  298.         FrameRect(&itemRect);
  299.         GetFNum((**gSettingHandle).fontName, &fontNumber);
  300.         saveRgn = NewRgn();
  301.         GetClip(saveRgn);
  302.         ClipRect(&itemRect);
  303.         DrawCalendar(
  304.             gSettingHandle,
  305.             gNow.year,
  306.             gNow.month,
  307.             &itemRect
  308.         );
  309.         SetClip(saveRgn);
  310.         DisposeRgn(saveRgn);
  311.         TextFont(saveFontNumber);
  312.         TextSize(saveFontSize);
  313.         SetPort(savePort);
  314. }
  315.  
  316. /////////////////////////////////////////////////////////////////////////
  317.  
  318. static void
  319. SetThisDayName(
  320.         short                    itemNumber,
  321.         ConstStr255Param        itemText
  322.     )
  323. {
  324.         short                itemType;
  325.         Handle                itemHandle;
  326.         Rect                itemRect;
  327.  
  328.         GetDialogItem(
  329.             gSetupDialog,
  330.             itemNumber,
  331.             &itemType,
  332.             &itemHandle,
  333.             &itemRect
  334.         );
  335.         SetDialogItemText(itemHandle, itemText);
  336. }
  337.  
  338. /////////////////////////////////////////////////////////////////////////
  339.  
  340. static void
  341. SetupDialog(void)
  342. {
  343.         short                nMenuItems;
  344.         short                i;
  345.         Str255                work;
  346.         Str255                fontSizeText;
  347.         short                itemType;
  348.         Handle                itemHandle;
  349.         Rect                itemRect;
  350.         StringPtr            dayName;
  351.  
  352.         SetDialogDefaultItem(gSetupDialog, kOKButton);
  353.         SetDialogCancelItem(gSetupDialog, kCancelButton);
  354.         /*
  355.          * Set the font name popup menu
  356.          */
  357.         nMenuItems = CountMItems(GetMenu(MENU_Font));
  358.         for (i = 1; i <= nMenuItems; i++) {
  359.             GetMenuItemText(GetMenu(MENU_Font), i, work);
  360.             if (EqualString(work, (**gSettingHandle).fontName, FALSE, FALSE))
  361.                 break;
  362.         }
  363.         if (i <= nMenuItems) {
  364.             GetDialogItem(
  365.                 gSetupDialog,
  366.                 kFontNamePopupItem,
  367.                 &itemType,
  368.                 &itemHandle,
  369.                 &itemRect
  370.             );
  371.             SetControlValue((ControlHandle) itemHandle, i);
  372.         }
  373.         /*
  374.          * Set the font size popup menu
  375.          */
  376.         nMenuItems = CountMItems(GetMenu(MENU_FontSize));
  377.         NumToString((**gSettingHandle).fontSize, fontSizeText);
  378.         for (i = 1; i <= nMenuItems; i++) {
  379.             GetMenuItemText(GetMenu(MENU_FontSize), i, work);
  380.             if (EqualString(work, fontSizeText, FALSE, FALSE))
  381.                 break;
  382.         }
  383.         if (i <= nMenuItems) {
  384.             GetDialogItem(
  385.                 gSetupDialog,
  386.                 kFontSizePopupItem,
  387.                 &itemType,
  388.                 &itemHandle,
  389.                 &itemRect
  390.             );
  391.             SetControlValue((ControlHandle) itemHandle, i);
  392.         }
  393.         /*
  394.          * Set the first day popup menu
  395.          */
  396.         GetDialogItem(
  397.             gSetupDialog,
  398.             kFirstDayPopupItem,
  399.             &itemType,
  400.             &itemHandle,
  401.             &itemRect
  402.         );
  403.         SetControlValue(
  404.             (ControlHandle) itemHandle,
  405.             (**gSettingHandle).firstDayOfWeek
  406.         );
  407.         /*
  408.          * Set the calendar drawing procedure
  409.          */
  410.         GetDialogItem(
  411.             gSetupDialog,
  412.             kCalendarUserItem,
  413.             &itemType,
  414.             &itemHandle,
  415.             &itemRect
  416.         );
  417.         SetDialogItem(
  418.             gSetupDialog,
  419.             kCalendarUserItem,
  420.             itemType,
  421.             (Handle) gDrawCalendarUserItemUPP,
  422.             &itemRect
  423.         );
  424.         /*
  425.          * Setup the day name user item
  426.          */
  427.         GetDialogItem(
  428.             gSetupDialog,
  429.             kDayNameUserItem,
  430.             &itemType,
  431.             &itemHandle,
  432.             &itemRect
  433.         );
  434.         SetDialogItem(
  435.             gSetupDialog,
  436.             kDayNameUserItem,
  437.             itemType,
  438.             (Handle) gDrawDayNameUserItemUPP,
  439.             &itemRect
  440.         );
  441.         /*
  442.          * Move the current date string into the dialog edit records.
  443.          */
  444.         dayName = (StringPtr) &(**gSettingHandle).dayNameString[1];
  445.         i = ((**gSettingHandle).firstDayOfWeek == kFirstIsSunday)
  446.             ? kSundayText : kMondayText;
  447.         for (; i <= kSaturdayText; i++) {
  448.             SetThisDayName(i, dayName);
  449.             dayName = (StringPtr) &dayName[dayName[0] + 1];
  450.         }
  451.         if ((**gSettingHandle).firstDayOfWeek == kFirstIsMonday)
  452.             SetThisDayName(kSundayText, dayName);
  453. }
  454.  
  455. /////////////////////////////////////////////////////////////////////////
  456.  
  457. static OSErr
  458. ReadCurrentParameters(void)
  459. {
  460.         OSErr                    result;
  461.  
  462.         result = Gestalt(kControlStripCreator, (long *) &gSettingHandle);
  463.         if (result == noErr
  464.              && gSettingHandle != nil
  465.              && GetHandleSize((Handle) gSettingHandle) == sizeof (SavedSettings)
  466.              && (**gSettingHandle).signature == kControlStripCreator
  467.              && (**gSettingHandle).prefVersion == kPrefVersion) {
  468.             result = HandToHand( (Handle *) &gSettingHandle );
  469.         } else {
  470.             if (result == noErr) {
  471.                 result = gestaltUndefSelectorErr;
  472.             }
  473.         }
  474.         
  475.         if (gSettingHandle != nil) {
  476.             HLock( (Handle) gSettingHandle);
  477.         }
  478.         
  479.         return (result);
  480. }
  481.  
  482. /////////////////////////////////////////////////////////////////////////
  483.  
  484. static void
  485. SaveNewParameters(void)
  486. {
  487.         OSErr                    status;
  488.         SavedSettingsHandle        controlStripSettings;
  489.  
  490.         // Locate the control strip's settings handle.
  491.         
  492.         status = Gestalt(kControlStripCreator, (long *) &controlStripSettings);
  493.         QAssert(status == noErr);
  494.         QAssert(controlStripSettings != nil);
  495.         QAssert(GetHandleSize( (Handle) controlStripSettings) == sizeof (SavedSettings));
  496.         QAssert((**controlStripSettings).signature == kControlStripCreator);
  497.         QAssert((**controlStripSettings).prefVersion == kPrefVersion);
  498.         
  499.         // Copy the new settings into the control strip's preferences.
  500.         
  501.         pstrcpy( (**controlStripSettings).dayNameString , (**gSettingHandle).dayNameString );
  502.         pstrcpy( (**controlStripSettings).fontName , (**gSettingHandle).fontName );
  503.         (**controlStripSettings).fontSize = (**gSettingHandle).fontSize;
  504.         (**controlStripSettings).firstDayOfWeek = (**gSettingHandle).firstDayOfWeek;
  505.         
  506.         // Bump the modification count so that the control strip knows we
  507.         // want it to save the settings.
  508.         (**controlStripSettings).modCount += 1;
  509. }
  510.  
  511. /////////////////////////////////////////////////////////////////////////
  512.  
  513. static void
  514. InitApplication(void)
  515. {
  516.         Handle                    menuBarHdl;
  517.         
  518.         InitGraf(&qd.thePort);
  519.         InitFonts();
  520.         InitWindows();
  521.         InitMenus();
  522.         TEInit();
  523.         InitDialogs(0);
  524.         MaxApplZone();
  525.  
  526.         menuBarHdl = GetNewMBar(MBAR_MenuBar);
  527.         SetMenuBar(menuBarHdl);
  528.         AppendResMenu(GetMenuHandle(MENU_Apple), 'DRVR');
  529.         AppendResMenu(GetMenu(MENU_Font), 'FONT');
  530.  
  531.         DrawMenuBar();
  532.  
  533.         gAppResourceFile = CurResFile();
  534.  
  535.         gDrawCalendarUserItemUPP = NewUserItemProc(DrawCalendarUserItem);
  536.         gDrawDayNameUserItemUPP = NewUserItemProc(DrawDayNameUserItem);
  537.  
  538.         InitCursor();
  539. }
  540.  
  541. /////////////////////////////////////////////////////////////////////////
  542.  
  543. static Boolean
  544. DoDialog(void)
  545. {
  546.         short                itemHit;
  547.         short                itemType;
  548.         Handle                itemHandle;
  549.         Rect                itemRect;
  550.         short                i;
  551.         Str255                work;
  552.         Boolean                redraw;
  553.         long                newFontSize;
  554.         
  555.         ShowWindow(gSetupDialog);
  556.         do {
  557.             ModalDialog(NULL, &itemHit);
  558.             GetDialogItem(
  559.                 gSetupDialog,
  560.                 itemHit,
  561.                 &itemType,
  562.                 &itemHandle,
  563.                 &itemRect
  564.             );
  565.             redraw = FALSE;
  566.             switch (itemHit) {
  567.             case kFontNamePopupItem:
  568.                 i = GetControlValue((ControlHandle) itemHandle);
  569.                 GetMenuItemText(GetMenu(MENU_Font), i, work);
  570.                 if (EqualString((**gSettingHandle).fontName, work, FALSE, FALSE) == FALSE) {
  571.                     pstrcpy((**gSettingHandle).fontName, work);
  572.                     redraw = TRUE;
  573.                 }
  574.                 break;
  575.             case kFontSizePopupItem:
  576.                 i = GetControlValue((ControlHandle) itemHandle);
  577.                 GetMenuItemText(GetMenu(MENU_FontSize), i, work);
  578.                 StringToNum(work, &newFontSize);
  579.                 if (newFontSize != (**gSettingHandle).fontSize) {
  580.                     (**gSettingHandle).fontSize = newFontSize;
  581.                     redraw = TRUE;
  582.                 }
  583.                 break;
  584.             case kFirstDayPopupItem:
  585.                 i =    GetControlValue((ControlHandle) itemHandle);
  586.                 if (i != (**gSettingHandle).firstDayOfWeek) {
  587.                     (**gSettingHandle).firstDayOfWeek = i;
  588.                     redraw = TRUE;
  589.                 }
  590.                 break;
  591. #if DEBUG
  592.             /*
  593.              * This lets us test the drawing algorithm without rebuilding the
  594.              * actual status bar and rebooting the machine.
  595.              */
  596.             case kPrevMonth:
  597.                 if (--gNow.month < 1) {
  598.                     gNow.month = 12;
  599.                     --gNow.year;
  600.                 }
  601.                 redraw = TRUE;
  602.                 break;
  603.             case kNextMonth:
  604.                 if (++gNow.month > 12) {
  605.                     gNow.month = 1;
  606.                     ++gNow.year;
  607.                 }
  608.                 redraw = TRUE;
  609.                 break;
  610. #endif
  611.             default:
  612.                 if (itemHit >= kSundayText && itemHit <= kSaturdayText)
  613.                     redraw = TRUE;
  614.                 break;
  615.             }
  616.             if (redraw)
  617.                 DrawCalendarUserItem(gSetupDialog, kCalendarUserItem);
  618.         } while (itemHit != kOKButton && itemHit != kCancelButton);
  619.         return (itemHit == kOKButton);
  620. }
  621.  
  622. /////////////////////////////////////////////////////////////////////////
  623.  
  624. void
  625. main(void)
  626. {
  627.         unsigned long            nowSeconds;
  628.         Boolean                    updateNeeded;
  629.         
  630.         InitApplication();
  631.         GetDateTime(&nowSeconds);
  632.         SecondsToDate(nowSeconds, &gNow);
  633.         gSetupDialog = GetNewDialog(DLOG_Setup, NULL, (WindowPtr) -1L);
  634.         if (gSetupDialog != NULL) {
  635.             if (ReadCurrentParameters() != noErr) {
  636.                 NoteAlert(ALRT_NoPreferences, NULL);
  637.             } else {
  638.                 SetupDialog();
  639.                 updateNeeded = DoDialog();
  640.                 if (updateNeeded) {
  641.                     SaveNewParameters();
  642.                 }
  643.             }
  644.             DisposeDialog(gSetupDialog);
  645.         }
  646.         ExitToShell();
  647. }
  648.